home *** CD-ROM | disk | FTP | other *** search
/ The World's Largest Collection of Windows Software / The World's Largest Collection of Windows Software - Disc 1.iso / connect / _j2 / wvnsc926 / rcs / wvcrypt.c < prev    next >
C/C++ Source or Header  |  1994-09-21  |  11KB  |  440 lines

  1. head    1.4;
  2. access;
  3. symbols;
  4. locks; strict;
  5. comment    @ * @;
  6.  
  7.  
  8. 1.4
  9. date    94.05.26.22.58.38;    author jglasser;    state Exp;
  10. branches;
  11. next    1.3;
  12.  
  13. 1.3
  14. date    93.12.27.20.13.46;    author mrr;    state Exp;
  15. branches;
  16. next    1.2;
  17.  
  18. 1.2
  19. date    93.12.08.01.28.38;    author rushing;    state Exp;
  20. branches;
  21. next    1.1;
  22.  
  23. 1.1
  24. date    93.07.13.16.03.04;    author riordan;    state Exp;
  25. branches;
  26. next    ;
  27.  
  28.  
  29. desc
  30. @authinfo support
  31. @
  32.  
  33.  
  34. 1.4
  35. log
  36. @warnings
  37. @
  38. text
  39. @/*--- wvcrypt.c -- Simple encryption routines for WinVN.
  40.  *
  41.  *  These simple encryption/decryption routines are used to
  42.  *  protect the user's NNTP server password.
  43.  *  The lack of sophistication is meant to protect the
  44.  *  exportability of this code.    For better stuff, see the
  45.  *  non-anonymous FTP site ripem.msu.edu.
  46.  */
  47.  
  48. /*
  49.  * $Id: wvcrypt.c 1.3 1993/12/27 20:13:46 mrr Exp jglasser $
  50.  */
  51.  
  52. #include <time.h>
  53. #include <string.h>
  54. #include <stdlib.h>
  55.  
  56. /* #define DEBUG 1 */
  57.  
  58. #define ROTORSIZE 256
  59. #define NSEEDBYTES 4
  60. #define RANBUFSIZE 15
  61. #define RANLAG1     9
  62. #define RANLAG2     14
  63.  
  64. static unsigned char RanbufMaster[RANBUFSIZE] = {
  65.     0, 0, 0, 0, 56, 34, 199, 77, 245, 252, 17, 184, 130, 215, 102 };
  66. static unsigned char *Ranbuf;
  67. static Ranidx;
  68.  
  69. void MRRMakeRotors(unsigned char *ranbuf, unsigned char *rotorE,
  70.  unsigned char *rotorD);
  71. int MRRRan(unsigned char *Ranbuf);
  72. int prencode (unsigned char *bufin , unsigned int nbytes , char *bufcoded );
  73. int prdecode (char *bufcoded , unsigned char *bufplain , int outbufsize );
  74.  
  75.  
  76.  
  77. /*--- function MRREncrypt ------------------------------------------
  78.  *
  79.  *  Encrypt and printably encode a sequence of bytes.
  80.  *
  81.  *  Entry:    plainText    is the input plaintext (binary bytes).
  82.  *             len            is the number of bytes in the above.
  83.  *             cipherText    is an output buffer that must be
  84.  *                             2*len+6 bytes long.
  85.  *
  86.  *  Exit:    cipherText    is a zero-terminated ASCII printable
  87.  *                             string of ciphertext.
  88.  */
  89. void
  90. MRREncrypt(unsigned char *plainText,int len,char *cipherText)
  91. {
  92.     time_t mytime;
  93.     int j;
  94.     unsigned char prev=0;
  95.     unsigned char *cipbuf, *cipbuforig;
  96.     unsigned char ranbuf[RANBUFSIZE], rotorE[ROTORSIZE], rotorD[ROTORSIZE];
  97.  
  98.     if(!len) {
  99.         cipherText[0] = '\0';
  100.         return;
  101.     }
  102.     cipbuf = cipbuforig = malloc (len+4);
  103.  
  104.     time(&mytime);
  105.     memcpy(ranbuf,RanbufMaster,RANBUFSIZE);
  106.     for(j=0; j<NSEEDBYTES; j++) {
  107.         cipbuf[j] = ranbuf[j] = (unsigned char) (mytime & 0xff);
  108.         mytime >>= 8;
  109.     }
  110.  
  111.     MRRMakeRotors(ranbuf,rotorE, rotorD);
  112.  
  113.     for(j=0; j<len; j++) {
  114.         cipbuf[j+NSEEDBYTES] = prev = rotorE[(*(plainText++)+prev)%ROTORSIZE];
  115.     }
  116.  
  117.     prencode(cipbuf,len+NSEEDBYTES,cipherText);
  118.     free(cipbuforig);
  119. }
  120.  
  121. int
  122. MRRDecrypt(char *cipherText,unsigned char *plainText, int plainMax)
  123. {
  124.     unsigned char prev=0;
  125.     unsigned char *cipbuf, *cipbuforig;
  126.     unsigned char ranbuf[RANBUFSIZE], rotorE[ROTORSIZE], rotorD[ROTORSIZE];
  127.     int j, nbytes, ch;
  128.  
  129.     if(!strlen(cipherText)) {
  130.         plainText[0] = '\0';
  131.         return 0;
  132.     }
  133.  
  134.     cipbuf = cipbuforig = malloc(plainMax+4);
  135.  
  136.     nbytes = prdecode(cipherText,cipbuf,plainMax) - NSEEDBYTES;
  137.     memcpy(ranbuf,RanbufMaster,RANBUFSIZE);
  138.     memcpy(ranbuf,cipbuf,NSEEDBYTES);
  139.     MRRMakeRotors(ranbuf,rotorE, rotorD);
  140.  
  141.     cipbuf += NSEEDBYTES;
  142.     for(j=0; j<nbytes; j++) {
  143.         ch = (int)rotorD[*cipbuf] - (int)prev;
  144.         if(ch < 0) ch += ROTORSIZE;
  145.         prev = *cipbuf;
  146.         *(plainText++) = ch;
  147.         cipbuf++;
  148.     }
  149.  
  150.     free(cipbuforig);
  151.     return nbytes;
  152. }
  153.  
  154.  
  155. /*--- function MRRMakeRotors -----------------------------------------
  156.  *
  157.  *  Set up the rotors used for encryption/decryption.
  158.  *
  159.  *  Entry:    Ranbuf is a buffer of "random" bytes.
  160.  *
  161.  *  Exit:    rotorE and rotorD are the encryption and
  162.  *             corresponding decryption rotors.
  163.  */
  164. void
  165. MRRMakeRotors(unsigned char *ranbuf, unsigned char *rotorE,
  166.  unsigned char *rotorD)
  167. {
  168.     int j, k, idx;
  169.     unsigned char ch;
  170.  
  171.     /* Make a standard reflexive rotor. */
  172.     for(j=0; j<ROTORSIZE; j++) {
  173.         rotorE[j] = j;
  174.     }
  175.     Ranidx = 0;
  176.  
  177.     /* Permute the rotor */
  178.     for(k=2; k; k--) for(j=ROTORSIZE-1; j; j--) {
  179.         idx = MRRRan(ranbuf);
  180.         /* This code omitted: idx = idx%(j+1); */
  181.         ch = rotorE[j];
  182.         rotorE[j] = rotorE[idx];
  183.         rotorE[idx] = ch;
  184.     }
  185.  
  186.     /* Create rotorD as the inverse of rotorE */
  187.     for(j=0; j<ROTORSIZE; j++) {
  188.         rotorD[rotorE[j]] = j;
  189.     }
  190.  
  191. #ifdef DEBUGMRR
  192.     printf("rotorE:\n");
  193.     for(j=0; j<ROTORSIZE; j++) {
  194.         printf("%4d",rotorE[j]);
  195.         if((j+1)%16 == 0) printf("\n");
  196.     }
  197.     printf("rotorD:\n");
  198.     for(j=0; j<ROTORSIZE; j++) {
  199.         printf("%4d",rotorD[j]);
  200.         if((j+1)%16 == 0) printf("\n");
  201.     }
  202. #endif
  203. }
  204.  
  205. /*--- function MRRRan --------------------------------------------------
  206.  *
  207.  *  Return a pseudorandom number in the range 0-255.
  208.  *  Uses an additive linear shift register.
  209.  *
  210.  *  Entry:    Ranbuf    is a buffer of RANBUFSIZE random bytes.
  211.  *             Ranidx    is an index into this buffer.
  212.  *
  213.  *  Exit:    Ranidx has been decremented.
  214.  *             Returns the next pseudorandom number.
  215.  */
  216. int
  217. MRRRan(unsigned char *Ranbuf)
  218. {
  219.     int idx1, idx2;
  220.  
  221.     if(--Ranidx < 0) Ranidx = RANBUFSIZE-1;
  222.     idx1 = Ranidx+RANLAG1;
  223.     if(idx1>=RANBUFSIZE) idx1 -= RANBUFSIZE;
  224.     idx2 = Ranidx+RANLAG2;
  225.     if(idx2>=RANBUFSIZE) idx2 -= RANBUFSIZE;
  226.  
  227.     Ranbuf[Ranidx] = 0xff & (Ranbuf[idx1] + Ranbuf[idx2] + Ranbuf[Ranidx]);
  228.  
  229.     return Ranbuf[Ranidx];
  230. }
  231.  
  232.  
  233. /*--- prencode.c -- File containing routines to convert a buffer
  234.  *  of bytes to/from RFC 1113 printable encoding format.
  235.  *
  236.  *  This technique is similar to the familiar Unix uuencode
  237.  *  format in that it maps 6 binary bits to one ASCII
  238.  *  character (or more aptly, 3 binary bytes to 4 ASCII
  239.  *  characters).  However, RFC 1113 does not use the same
  240.  *  mapping to printable characters as uuencode.
  241.  *
  242.  *  Mark Riordan   12 August 1990 and 17 Feb 1991.
  243.  *  This code is hereby placed in the public domain.
  244.  */
  245.  
  246.  
  247. static char six2pr[64] = {
  248. 'A','B','C','D','E','F','G','H','I','J','K','L','M',
  249. 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
  250. 'a','b','c','d','e','f','g','h','i','j','k','l','m',
  251. 'n','o','p','q','r','s','t','u','v','w','x','y','z',
  252. '0','1','2','3','4','5','6','7','8','9','+','/'        };
  253.  
  254. /*--- function prencode -----------------------------------------------
  255.  *
  256.  *   Encode a single line of binary data to a standard format that
  257.  *   uses only printing ASCII characters (but takes up 33% more bytes).
  258.  *
  259.  *    Entry    bufin    points to a buffer of bytes.  If nbytes is not
  260.  *                      a multiple of three, then the byte just beyond
  261.  *                      the last byte in the buffer must be 0.
  262.  *             nbytes   is the number of bytes in that buffer.
  263.  *             bufcoded points to an output buffer.  Be sure that this
  264.  *                      can hold at least 1 + (4*nbytes)/3 characters.
  265.  *
  266.  *    Exit     bufcoded contains the coded line.  The first 4*nbytes/3 bytes
  267.  *                      contain printing ASCII characters representing
  268.  *                      those binary bytes. This may include one or
  269.  *                      two '=' characters used as padding at the end.
  270.  *                      The last byte is a zero byte.
  271.  *             Returns the number of ASCII characters in "bufcoded".
  272.  */
  273. int
  274. prencode(bufin, nbytes, bufcoded)
  275. unsigned char *bufin;
  276. unsigned int nbytes;
  277. char *bufcoded;
  278. {
  279. /* ENC is the basic 1 character encoding function to make a char printing */
  280. #define ENC(c) six2pr[c]
  281.  
  282.    register char *outptr = bufcoded;
  283.    unsigned int i;
  284.  
  285.    for (i=0; i<nbytes; i += 3) {
  286.       *(outptr++) = ENC(*bufin >> 2);            /* c1 */
  287.       *(outptr++) = ENC(((*bufin << 4) & 060) | ((bufin[1] >> 4) & 017));  /* c2 */
  288.       *(outptr++) = ENC(((bufin[1] << 2) & 074) | ((bufin[2] >> 6) & 03)); /* c3 */
  289.       *(outptr++) = ENC(bufin[2] & 077);         /* c4 */
  290.  
  291.       bufin += 3;
  292.    }
  293.  
  294.    /* If nbytes was not a multiple of 3, then we have encoded too
  295.     * many characters.  Adjust appropriately.
  296.     */
  297.    if(i == nbytes+1) {
  298.       /* There were only 2 bytes in that last group */
  299.       outptr[-1] = '=';
  300.    } else if(i == nbytes+2) {
  301.       /* There was only 1 byte in that last group */
  302.       outptr[-1] = '=';
  303.       outptr[-2] = '=';
  304.    }
  305.    *outptr = '\0';
  306.    return(outptr - bufcoded);
  307. }
  308.  
  309. /*--- function prdecode ------------------------------------------------
  310.  *
  311.  *  Decode an ASCII-encoded buffer back to its original binary form.
  312.  *
  313.  *     Entry     bufcoded     points to a encoded string.    It is
  314.  *                         terminated by any character not in
  315.  *                         the printable character table six2pr, but
  316.  *                         leading whitespace is stripped.
  317.  *             bufplain    points to the output buffer; must be big
  318.  *                         enough to hold the decoded string (generally
  319.  *                         shorter than the encoded string) plus
  320.  *                         as many as two extra bytes used during
  321.  *                         the decoding process.
  322.  *             outbufsize  is the maximum number of bytes that
  323.  *                         can fit in bufplain.
  324.  *
  325.  *    Exit     Returns the number of binary bytes decoded.
  326.  *             bufplain    contains these bytes.
  327.  */
  328. int
  329. prdecode(bufcoded,bufplain,outbufsize)
  330. char *bufcoded;
  331. unsigned char *bufplain;
  332. int outbufsize;
  333. {
  334. /* single character decode */
  335. #define DEC(c) pr2six[(int)c]
  336. #define MAXVAL 63
  337.  
  338.    int nbytesdecoded, j;
  339.    register char *bufin = bufcoded;
  340.    register unsigned char *bufout = bufplain;
  341.    register int nprbytes;
  342.     unsigned char pr2six[256];
  343.  
  344.  
  345.     /* Initialize the mapping table.
  346.     * This code should work even on non-ASCII machines.
  347.     */
  348.     for(j=0; j<256; j++) pr2six[j] = MAXVAL+1;
  349.  
  350.     for(j=0; j<64; j++) pr2six[(int)six2pr[j]] = (unsigned char) j;
  351.  
  352.    /* Strip leading whitespace. */
  353.  
  354.    while(*bufcoded==' ' || *bufcoded == '\t') bufcoded++;
  355.  
  356.    /* Figure out how many characters are in the input buffer.
  357.     * If this would decode into more bytes than would fit into
  358.     * the output buffer, adjust the number of input bytes downwards.
  359.     */
  360.    bufin = bufcoded;
  361.    while(pr2six[(int)*(bufin++)] <= MAXVAL);
  362.    nprbytes = bufin - bufcoded - 1;
  363.    nbytesdecoded = ((nprbytes+3)/4) * 3;
  364.    if(nbytesdecoded > outbufsize) {
  365.       nprbytes = (outbufsize*4)/3;
  366.    }
  367.  
  368.    bufin = bufcoded;
  369.    
  370.    while (nprbytes > 0) {
  371.       *(bufout++) = (unsigned char) (DEC(*bufin) << 2 | DEC(bufin[1]) >> 4);
  372.       *(bufout++) = (unsigned char) (DEC(bufin[1]) << 4 | DEC(bufin[2]) >> 2);
  373.       *(bufout++) = (unsigned char) (DEC(bufin[2]) << 6 | DEC(bufin[3]));
  374.       bufin += 4;
  375.       nprbytes -= 4;
  376.    }
  377.    
  378.    if(nprbytes & 03) {
  379.       if(pr2six[(int)bufin[-2]] > MAXVAL) {
  380.          nbytesdecoded -= 2;
  381.       } else {
  382.          nbytesdecoded -= 1;
  383.       }
  384.    }
  385.  
  386.    return(nbytesdecoded);
  387. }
  388. @
  389.  
  390.  
  391. 1.3
  392. log
  393. @fixed memory management bug
  394. @
  395. text
  396. @d11 1
  397. a11 1
  398.  * $Id: wvcrypt.c 1.2 1993/12/08 01:28:38 rushing Exp mrr $
  399. d69 1
  400. a69 1
  401.         cipbuf[j] = ranbuf[j] = mytime & 0xff;
  402. @
  403.  
  404.  
  405. 1.2
  406. log
  407. @new version box and cr lf consistency
  408. @
  409. text
  410. @d11 1
  411. a11 1
  412.  * $Id:$
  413. d57 1
  414. a57 1
  415.     unsigned char *cipbuf = malloc(len+4);
  416. d64 1
  417. d80 1
  418. a80 1
  419.     free(cipbuf);
  420. d87 1
  421. a87 1
  422.     unsigned char *cipbuf = malloc(plainMax+4);
  423. d96 2
  424. d112 1
  425. a112 1
  426.     free(cipbuf);
  427. d153 1
  428. a153 1
  429. #ifdef DEBUG
  430. @
  431.  
  432.  
  433. 1.1
  434. log
  435. @Initial revision
  436. @
  437. text
  438. @d10 4
  439. @
  440.